package com.ionehe.group.common.uaa.ex.domain.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.ionehe.group.common.io.Paging;
import com.ionehe.group.common.io.Response;
import com.ionehe.group.common.uaa.ex.convert.UaaDataItemConvert;
import com.ionehe.group.common.uaa.ex.dao.UaaDataItemDao;
import com.ionehe.group.common.uaa.ex.domain.service.UaaDataItemService;
import com.ionehe.group.common.uaa.ex.dto.UaaDataItemDTO;
import com.ionehe.group.common.uaa.ex.enums.ErrorMessages;
import com.ionehe.group.common.uaa.ex.enums.IsDelete;
import com.ionehe.group.common.uaa.ex.exception.BusinessException;
import com.ionehe.group.common.uaa.ex.model.UaaDataItem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * uaa数据项信息表(UaaDataItem)服务实现类
 *
 * @author makejava
 * @since 2021-12-27 17:07:24
 */
@Service
@Slf4j
public class UaaDataItemServiceImpl implements UaaDataItemService {
    @Resource
    private UaaDataItemDao dao;
    @Autowired
    private UaaDataItemConvert convert;
    @Autowired
    private PlatformTransactionManager tx;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Response<UaaDataItemDTO> queryById(Long id) {
        if (Objects.isNull(id)) return Response.no(ErrorMessages.ILLEGAL_PARAMS.toString());

        try {
            Example e = new Example(UaaDataItem.class);
            e.createCriteria()
                    .andEqualTo("id", id)
                    .andEqualTo("isDelete", IsDelete.FALSE.getValue());

            log.info("ACCESS_LOG[]UaaDataItemService[]queryById[]select uaaDataItem");

            List<UaaDataItem> uaaDataItemList = dao.selectByExample(e);

            if (CollUtil.isEmpty(uaaDataItemList))
                return Response.yes();

            UaaDataItem uaaDataItem = uaaDataItemList.get(0);

            UaaDataItemDTO uaaDataItemDTO = convert.do2dto(uaaDataItem);

            return Response.yes(uaaDataItemDTO);
        } catch (BusinessException e) {
            log.error("UaaDataItemService[]queryById[]error! cause:{}", Throwables.getStackTraceAsString(e));
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UaaDataItemService[]queryById[]error! cause:{}", Throwables.getStackTraceAsString(e));
            return Response.no();
        }
    }

    /**
     * 分页查询多条数据
     *
     * @param pageNum    当前页
     * @param pageSize   查询条数
     * @param conditions 查询条件
     * @return 对象列表
     */
    @Override
    public Response<Paging<UaaDataItemDTO>> paging(Integer pageNum, Integer pageSize, Map<String, String> conditions) {
        try {
            Example example = new Example(UaaDataItem.class);
            example.setOrderByClause("id asc");
            Example.Criteria criteria = example.createCriteria()
                    .andEqualTo("isDelete", IsDelete.FALSE.getValue());

            if (conditions != null) {
                conditions.forEach((k, v) -> criteria.andLike(k, "%" + v + "%"));
            }

            Page<Object> page = null;

            if (Objects.nonNull(pageNum) && Objects.nonNull(pageSize)) {
                page = PageMethod.startPage(pageNum, pageSize);
            }

            log.info("ACCESS_LOG[]UaaDataItemService[]paging[]select uaaDataItem");

            List<UaaDataItem> uaaDataItemList = dao.selectByExample(example);
            List<UaaDataItemDTO> uaaDataItemDTOList = convert.do2dto(uaaDataItemList);

            Paging<UaaDataItemDTO> paging = new Paging<>();

            paging.setData(uaaDataItemDTOList);
            paging.setTotal((long) uaaDataItemDTOList.size());
            if (page != null) paging.setTotal(page.getTotal());

            return Response.yes(paging);
        } catch (BusinessException e) {
            log.error("UaaDataItemService[]paging[]error! cause:{}", Throwables.getStackTraceAsString(e));
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UaaDataItemService[]paging[]error! cause:{}", Throwables.getStackTraceAsString(e));
            return Response.no();
        }
    }

    /**
     * 新增数据
     *
     * @param uaaDataItemDTO 实例对象
     * @return 是否成功
     */
    @Override
    public Response<Boolean> insert(UaaDataItemDTO uaaDataItemDTO) {
        if (Objects.isNull(uaaDataItemDTO)) return Response.no(ErrorMessages.ILLEGAL_PARAMS.toString());

        TransactionStatus status = tx.getTransaction(new DefaultTransactionDefinition());

        try {
            UaaDataItem uaaDataItem = convert.dto2do(uaaDataItemDTO);

            int i = dao.insertSelective(uaaDataItem);
            if (i != 1) {
                throw new BusinessException();
            }

            log.info("OP_LOG[]UaaDataItemService[]insert[]insert uaaDataItem success!");

            tx.commit(status);

            return Response.yes(true);
        } catch (BusinessException e) {
            log.error("UaaDataItemService[]insert[]error! cause:{}", Throwables.getStackTraceAsString(e));
            tx.rollback(status);
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UaaDataItemService[]insert[]error! cause:{}", Throwables.getStackTraceAsString(e));
            tx.rollback(status);
            return Response.no();
        }
    }

    /**
     * 修改数据
     *
     * @param uaaDataItemDTO 实例对象
     * @return 是否成功
     */
    @Override
    public Response<Boolean> update(UaaDataItemDTO uaaDataItemDTO) {
        if (Objects.isNull(uaaDataItemDTO)) return Response.no(ErrorMessages.ILLEGAL_PARAMS.toString());

        TransactionStatus status = tx.getTransaction(new DefaultTransactionDefinition());

        try {
            log.info("ACCESS_LOG[]UaaDataItemService[]update[]select uaaDataItem");

            selectByIdList(Lists.newArrayList(uaaDataItemDTO.getId()));

            UaaDataItem uaaDataItem = convert.dto2do(uaaDataItemDTO);

            uaaDataItem.setUpdatedAt(new Date());

            int i = dao.updateByPrimaryKeySelective(uaaDataItem);

            if (i < 1) {
                throw new BusinessException();
            }

            log.info("OP_LOG[]UaaDataItemService[]update[]update uaaDataItem success!");

            tx.commit(status);

            return Response.yes(true);
        } catch (BusinessException e) {
            log.error("UaaDataItemService[]update[]error! cause:{}", Throwables.getStackTraceAsString(e));
            tx.rollback(status);
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UaaDataItemService[]update[]error! cause:{}", Throwables.getStackTraceAsString(e));
            tx.rollback(status);
            return Response.no();
        }
    }

    /**
     * 通过主键删除数据
     *
     * @param ids 主键集合
     * @return 是否成功
     */
    @Override
    public Response<Boolean> del(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) return Response.no(ErrorMessages.ILLEGAL_PARAMS.toString());

        TransactionStatus status = tx.getTransaction(new DefaultTransactionDefinition());

        try {
            log.info("ACCESS_LOG[]UaaDataItemService[]del[]select uaaDataItem");

            selectByIdList(ids);

            Example e = new Example(UaaDataItem.class);
            e.createCriteria().andIn("id", ids);

            UaaDataItem d = UaaDataItem.builder()
                    .isDelete(IsDelete.TRUE.getValue())
                    .updatedAt(new Date())
                    .build();

            int i = dao.updateByExampleSelective(d, e);
            if (i < 1) {
                throw new BusinessException();
            }

            log.info("OP_LOG[]UaaDataItemService[]del[]update uaaDataItem status success!");

            tx.commit(status);

            return Response.yes(true);
        } catch (BusinessException e) {
            log.error("UaaDataItemService[]del[]error! cause:{}", Throwables.getStackTraceAsString(e));
            tx.rollback(status);
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UaaDataItemService[]del[]error! cause:{}", Throwables.getStackTraceAsString(e));
            tx.rollback(status);
            return Response.no();
        }
    }

    @Override
    public Response<List<UaaDataItemDTO>> queryByCode(String code) {
        try {
            Example exa = new Example(UaaDataItem.class);
            exa.createCriteria()
                    .andEqualTo("isDelete", IsDelete.FALSE.getValue())
                    .andEqualTo("code", code);

            List<UaaDataItem> uaaDataItemList = dao.selectByExample(exa);

            return Response.yes(convert.do2dto(uaaDataItemList));
        } catch (Exception e) {
            log.warn("UaaDataItemService[]queryByCode[]error! cause:{}", Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.GET_DATA_ITEM_FAIL.toString());
        }
    }

    /**********************************              service函数分界线             **************************************/

    /**
     * 根据id查询
     */
    private List<UaaDataItem> selectByIdList(List<Long> ids) {
        Example e = new Example(UaaDataItem.class);
        e.createCriteria()
                .andIn("id", ids)
                .andEqualTo("isDelete", IsDelete.FALSE.getValue());

        List<UaaDataItem> uaaDataItemList = dao.selectByExample(e);

        if (CollUtil.isEmpty(uaaDataItemList) || ids.size() != uaaDataItemList.size()) {
            throw new BusinessException(ErrorMessages.ILLEGAL_OPERATION.toString());
        }

        return uaaDataItemList;
    }
}